import 'dart:async';
import 'dart:io';

import 'package:cloudbase_auth/cloudbase_auth.dart';
import 'package:cloudbase_core/cloudbase_core.dart';
import 'package:cloudbase_database/cloudbase_database.dart';
import 'package:cloudbase_function/cloudbase_function.dart';
import 'package:cloudbase_storage/cloudbase_storage.dart';
import 'package:flutter/material.dart';
import 'package:flutter_easyloading/flutter_easyloading.dart';
import 'package:flutter_vant_kit/widgets/addressList.dart';
import 'package:provider/provider.dart';
import 'package:shoes_shop/core/utils.dart';
import 'package:shoes_shop/models/address_model.dart';
import 'package:shoes_shop/models/cart_model.dart';
import 'package:shoes_shop/models/public_provider_model.dart';
import 'package:shoes_shop/models/shoe_model.dart';

CloudBaseCore core;
CloudBaseAuth auth = CloudBaseAuth(core);
CloudBaseAuthState authState;
CloudBaseDatabase db = CloudBaseDatabase(core);
CloudBaseFunction cloudbase = CloudBaseFunction(core);
CloudBaseStorage storage = CloudBaseStorage(core);

// 请求参数
// CloudBaseFunction cloudbase = CloudBaseFunction(core);
// Map<String, dynamic> data = {'a': 10, 'b': 2};
// CloudBaseResponse res = await cloudbase.callFunction('node-app', data);
// print(res);

//插入数据库
// collection.add({'title': '测试'}).then((res) {print('结果: $res');}).catchError((e) {print('错误: $e');});

//初始化
void init() async {
  var appAccess;
  //判断设备是苹果还是安卓：
  if (Platform.isIOS) {
    print("IOS");
    //ios相关代码
    appAccess = {
      // 凭证
      'key': 'aee40ec20e8a06a24425be6d0c351651',
      // 版本
      'version': '1'
    };
  } else if (Platform.isAndroid) {
    print("安卓");
    //android相关代码
    appAccess = {
      // 凭证
      'key': '98fc53aac72369ebb3778fb4f2b10031',
      // 版本
      'version': '1'
    };
  } else {
    // 其他设备
    print('其他设备: $Platform');
  }
  // 初始化 CloudBase
  core = CloudBaseCore.init({
    // 填写您的云开发 env
    'env': 'sine-4gprdtyrccdf2c23',
    // 填写您的移动应用安全来源凭证
    // 生成凭证的应用标识必须是 Android 包名或者 iOS BundleID
    'appAccess': appAccess,
    // 请求超时时间（选填
    'timeout': 4000
  });
  print('CloudBase 初始化完成');
}

// 接口最小延迟2秒 防止频繁请求接口
minimumDelay(int _time, [int _minTime = 2000]) async {
  int _delayTime = DateTime.now().millisecondsSinceEpoch - _time;
  if (_delayTime >= _minTime) {
    return;
  } else {
    // Timer(Duration(microseconds: (2000 - _delayTime)), () {
    //   print('延迟之后');
    //   return res;
    // });
    await Future.delayed(Duration(milliseconds: (_minTime - _delayTime)));
    return;
  }
}

//邮箱注册
mailRegistration(String email, String password) async {
  print('注册 email:$email,password:$password');
  int _time = DateTime.now().millisecondsSinceEpoch;
  CloudBaseResponse res = await CloudBaseRequest(core).postWithoutAuth(
      'auth.signUpWithEmailAndPassword',
      {'email': email, 'password': password});
  print('注册返回$res');
  await minimumDelay(_time);
  if (res == null) {
    throw CloudBaseException(
        code: CloudBaseExceptionCode.NULL_RESPONES,
        message: "unknown error, res is null");
  }

  if (res.message == '[100003] pwd length too short') {
    return {'code': res.code, 'message': '密码太短'};
  }
  if (res.message == '[100003] pwd is weak') {
    return {'code': res.code, 'message': '密码过于简单'};
  }
  if (res.message == '[102002] mail user exist') {
    return {'code': res.code, 'message': '账户已经存在'};
  }
  if (res.code != null) {
    // throw CloudBaseException(code: res.code, message: res.message);
    return {'code': res.code, 'message': res.message};
  }
  return {'code': 200, 'message': '发送注册邮件成功，请注意查收 (｡･∀･)ﾉﾞ'};
}

//邮箱登录
mailLogin(context, String email, String password) async {
  print('邮箱登录 email:$email,password:$password');
  int _time = DateTime.now().millisecondsSinceEpoch;
  Map res;
  await auth.signInByEmail(email, password).then((value) async {
    await minimumDelay(_time);
    print('登录成功：${value.refreshToken}');
    var res1 = await getUserInfo(context);
    if (res1['code'] == 200) {
      res = {'code': 200, 'message': '登录成功'};
    } else {
      res = {'code': 0, 'message': '获取用户信息失败'};
    }
    return res;
  }).catchError((e) async {
    await minimumDelay(_time);
    print('登录失败：$e');
    String message;
    if (e.message.contains('102003')) {
      message = '邮箱或者用户不存在';
    } else {
      message = e.message;
    }
    res = {'code': -1, 'message': message};
  });
  return res;
}

//获取用户信息
getUserInfo(context) async {
  return await auth.getUserInfo().then((userInfo) {
    print('获取用户信息成功$userInfo');
    Provider.of<PublicProviderModel>(context, listen: false)
        .saveUserInfo(userInfo);
    return {'code': 200, 'messsage': '获取用户信息成功'};
  }).catchError((err) {
    print('获取用户信息失败$err');
    return {'code': 0, 'message': '获取用户信息失败'};
  });
}

// 修改用户信息
updateUserInfo(Map userInfo) async {
  print('上传的值$userInfo');
  try {
    var res = await auth.updateUserInfo(
      nickName: userInfo['nickname'],
      gender: userInfo['gender'] == 0 ? 'MALE' : 'FEMALE',
      avatarUrl: userInfo['avatarUrl'],
    );
    print('修改用户信息结果$res');
    return {'code': 200, 'message': '修改用户信息成功'};
  } catch (e) {
    print('修改用户信息失败$e');
    return {'code': 0, 'message': '修改用户信息失败'};
  }
}

// 退出登录
logout() async {
  await auth.signOut();
  return {'code': 200, 'message': '退出登录成功'};
}

//发送短信验证码
sendSmsCode() async {
  // int _time = DateTime.now().millisecondsSinceEpoch;
  CloudBaseResponse res = await CloudBaseRequest(core)
      .post('auth.sendPhoneCode', {'phoneNumber': '+8613511111111'});
  print('发送验证码结果:$res');
  // await minimumDelay(_time);
}

//帐号密码登录
// passWordLogin() async {
//   int _time = DateTime.now().millisecondsSinceEpoch;
//   CloudBaseResponse res = await cloudbase
//       .callFunction('loginPwd', {'id': 'admin', 'password': 'admin123'});
//   await minimumDelay(_time);
//   return res;
//   print('登录返回结果：$res');
// }

//获取商品列表
getGoodsList() async {
  try {
    Collection collection = db.collection('shoes');
    //查询数据库
    var res = await collection.get();
    print('获取商品列表$res');
    // var str = json.encode(res);
    // var list = jsonDecode(str);
    // var map = new Map<String, dynamic>.from(list);
    var data = new ShoeModel.fromJson(res);
    return data;
    // print(data.data[0].iCreateTime);
  } catch (e) {
    print('获取商品列表失败$e');
  }
}

// 文件上传
uploadFile(String cloudPath, String filePath) async {
  EasyLoading.show();
  CloudBaseStorageRes<UploadRes> res = await storage.uploadFile(
      cloudPath: cloudPath,
      filePath: filePath,
      onProcess: (int count, int total) {
        // // 当前进度
        // print(count);
        // // 总进度
        // print(total);
      });
  print('文件id${res.data.fileId}');
  List<String> fileIds = [res.data.fileId];
  CloudBaseStorageRes<List<DownloadMetadata>> res1 =
      await storage.getFileDownloadURL(fileIds);
  print('图片地址${res1.data[0]}');
  EasyLoading.dismiss();
  return res1.data[0].downloadUrl;
}

// 添加地址
addAddress(Map data) async {
  try {
    Collection collection = db.collection('address');
    dynamic postData = {
      "name": data['name'],
      "tel": data['tel'],
      "province": data['province'],
      "city": data['city'],
      "county": data['county'],
      "provinceId": data['provinceId'],
      "cityId": data['cityId'],
      "countyId": data['countyId'],
      "addressDetail": data['addressDetail'],
      "postalCode": data['postalCode'],
      "isDefault": data['isDefault'],
      "_createTime": DateTime.now().millisecondsSinceEpoch, // 待改为服务器时间
      "_updateTime": DateTime.now().millisecondsSinceEpoch,
    };
    await collection.add(postData);
    print('添加地址成功');
    return {'code': 200, 'message': '添加地址成功'};
  } catch (e) {
    print('添加地址失败:$e');
    return {'code': 0, 'message': '添加地址失败'};
  }
}

// 修改地址
editAddress(String id, Map data) async {
  try {
    Collection collection = db.collection('address');
    Map<String, dynamic> postData = {
      "name": data['name'],
      "tel": data['tel'],
      "province": data['province'],
      "city": data['city'],
      "county": data['county'],
      "provinceId": data['provinceId'],
      "cityId": data['cityId'],
      "countyId": data['countyId'],
      "addressDetail": data['addressDetail'],
      "postalCode": data['postalCode'],
      "isDefault": data['isDefault'],
      "_updateTime": DateTime.now().millisecondsSinceEpoch, // 待改为服务器时间
    };
    await collection.where({'_id': id}).update(postData);
    print('修改地址成功');
    return {'code': 200, 'message': '修改地址成功'};
  } catch (e) {
    print('修改地址失败:$e');
    return {'code': 0, 'message': '修改地址失败'};
  }
}

// 删除地址
deleteAddress(String id) async {
  try {
    Collection collection = db.collection('address');
    await collection.where({'_id': id}).remove();
    print('删除地址成功');
    return {'code': 200, 'message': '删除地址成功'};
  } catch (e) {
    print('删除地址失败:$e');
    return {'code': 0, 'message': '删除地址失败'};
  }
}

// 获取地址列表
getAddressList(String openid) async {
  try {
    Collection collection = db.collection('address');
    //查询数据库
    DbQueryResponse res = await collection.where({'_openid': openid}).get();
    // print('获取地址列表$res');
    var data = new AddressModel.fromJson(res);
    return {'code': 200, 'message': '获取地址列表成功', 'data': data.data};
  } catch (e) {
    print('获取地址列表失败$e');
    return {'code': 0, 'message': '获取地址列表失败'};
  }
}

//添加到购物车
addToCart(ShoeModelData item,BuildContext context ) async {
  
  try {
    Collection collection = db.collection('cart');
    List<CartModelData> _cartList = Provider.of<PublicProviderModel>(context, listen: false).cartList;
    String openid = Provider.of<PublicProviderModel>(context, listen: false).userInfo['openid'];
    if(openid == null){
      return {'code': 401, 'message': '请先登录'};
    }
    EasyLoading.show();
    var _index;
    for(var i=0; i<_cartList.length; i++){
      if(item.sId == _cartList[i].goodsId){
        _index = i;
        break;
      }
    }
    if(_index != null){
      _cartList[_index].count ++;
      await changeCartGoodsNum(_cartList[_index].sId,_cartList[_index].count,_index,context);
    }else{
      Map data = {
      "goods_id": item.sId,
      "count": 1,
      "_createTime": DateTime.now().millisecondsSinceEpoch, // 待改为服务器时间
      "_updateTime": DateTime.now().millisecondsSinceEpoch,
    };
      await collection.add(data);
      getCartList(context);
    }
    EasyLoading.dismiss();
    return {'code': 200, 'message': '添加到购物车成功'};
  } catch (e) {
    print('添加到购物车失败：$e');
    EasyLoading.dismiss();
    return {'code': 0, 'message': '添加到购物车失败'};
  }
}

//  获取购物车列表
getCartList(context) async {
  EasyLoading.show();
  try {
    CloudBaseResponse res = await cloudbase.callFunction('get-cart-list');
    logger.i('获取购物车成功$res');
    CartModel data = new CartModel.fromJson(res);
    Provider.of<PublicProviderModel>(context, listen: false)
        .providerGetCartList(data.data);
    EasyLoading.dismiss();
    return {'code': 200, 'message': '获取购物车成功', 'data': res.data};
  } catch (e) {
    print('获取购物车失败：$e');
    EasyLoading.dismiss();
    return {'cdoe': 0, 'message': '获取购物车列表失败'};
  }
}

// 修改购物车商品数量
changeCartGoodsNum(String id, int count, int index, context) async {
  try {    Collection collection = db.collection('cart');
    Map data = {
      "count": count,
      "_updateTime": DateTime.now().millisecondsSinceEpoch,
    };
    await collection.doc(id).update(data);
    Provider.of<PublicProviderModel>(context, listen: false)
        .changeGoodsNum(index,count);
    return {'code': 200, 'message': '修改购物商品成功'};
  } catch (e) {
    print('添加到购物车失败：$e');
    return {'code': 0, 'message': '修改购物商品车失败'};
  }
}

// 删除购物车商品
removeCartGoods(String id, int index, context){
  try{
    Collection collection = db.collection('cart');
    collection.doc(id).remove();
    Provider.of<PublicProviderModel>(context, listen: false)
        .removeGoods(index);
    return {'code': 200, 'message': '删除购物车商品成功'};
  }catch(e){
    print('删除购物车商品失败：$e');
    return {'code': 0, 'message': '删除购物车商品失败'};
  }
}

// 清空购物车
emptyCart(context){
  try{
    Collection collection = db.collection('cart');
    collection.where({
      '_openid': Provider.of<PublicProviderModel>(context, listen: false).userInfo['openid']
    }).remove();
    Provider.of<PublicProviderModel>(context, listen: false)
        .emptyCart();
    return {'code': 200, 'message': '清除购物车商品成功'};
  }catch(e){
    print('清除购物车商品失败：$e');
    return {'code': 0, 'message': '清除购物车商品失败'};
  }
}

// 结算商品
settlement(BuildContext context) async {
  EasyLoading.show();
  try {
    String openid = Provider.of<PublicProviderModel>(context, listen: false)
        .userInfo['openid'];
    CloudBaseResponse res =
        await cloudbase.callFunction('create-order', {'openid': openid});
    logger.i('结算商品成功$res');
    EasyLoading.dismiss();
    return {'code': 200, 'message': '结算商品成功', 'data': res.data};
  } catch (e) {
    EasyLoading.dismiss();
    print('结算商品失败：$e');
    return {'cdoe': 0, 'message': '结算商品失败'};
  }
}

// 立即支付
payment(String id, AddressInfo address) async {
  logger.i(id);
  EasyLoading.show();
  try {
    // 模拟延迟
    // await Future.delayed(Duration(milliseconds: 2000));
    Collection collection = db.collection('order');
    Map data = {
      'address': address.toJson(),
      "_updateTime": DateTime.now().millisecondsSinceEpoch,
    };
    DbQueryResponse res = await collection.get();
    await collection.doc(id).update(data);
    logger.i(res);
    EasyLoading.dismiss();
    return {'code': 200, 'message': '支付成功'};
  } catch (e) {
    EasyLoading.dismiss();
    print('支付失败：$e');
    return {'cdoe': 0, 'message': '支付失败'};
  }
}

// 获取订单列表
Future getOrder(int index,int page ,int limit) async {
  // EasyLoading.show();
  try {
    Collection collection = db.collection('order');
    //查询数据库
    DbQueryResponse res = await collection.where({'status': index}).skip(limit * (page - 1)).limit(limit).get();
    logger.i(res);
    // EasyLoading.dismiss();
    return {'code': 200, 'message': '获取订单成功', 'data': res.data};
  } catch (e) {
    // EasyLoading.dismiss();
    print('获取订单失败：$e');
    return {'cdoe': 0, 'message': '获取订单失败'};
  }
}

// 获取订单详情
getOrderDetail(String id) async {
  logger.i(id);
  try {
    Collection collection = db.collection('order');
    DbQueryResponse res = await collection.doc(id).get();
    logger.i(res);
    return {'code': 200, 'message': '获取订单详情成功'};
  } catch (e) {
    print('获取订单详情失败：$e');
    return {'code': 0, 'message': '获取订单详情失败'};
  }
}